package com.macro.mall.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.rholder.retry.*;
import com.macro.mall.common.api.CommonPage;
import com.macro.mall.common.config.XhsApiConfig;
import com.macro.mall.dto.XhsOrderDetailVO;
import com.macro.mall.dto.XhsOrderQueryParam;
import com.macro.mall.dto.XhsOrderVO;

import com.macro.mall.common.exception.BaseException;
import com.macro.mall.common.exception.XhsApiException;
import com.macro.mall.common.utils.AmountUtils;
import com.macro.mall.mapper.*;
import com.macro.mall.model.*;
import com.macro.mall.model.request.*;
import com.macro.mall.model.request.order.CreateOrderRequest;
import com.macro.mall.model.request.order.SelOrderRequest;
import com.macro.mall.model.request.order.StoreDetailRequest;
import com.macro.mall.model.response.*;
import com.macro.mall.model.vo.order.OrderDetail;
import com.macro.mall.model.vo.order.OrderList;
import com.macro.mall.model.vo.product.ProductDetailVo;
import com.macro.mall.model.vo.store.StoreDetailVo;
import com.macro.mall.service.ProductSyncService;
import com.macro.mall.service.XhsLoginService;
import com.macro.mall.service.XhsOrderService;

import com.macro.mall.utils.OrderNumberUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class XhsOrderServiceImpl implements XhsOrderService {

    @Resource
    private OkHttpClient httpClient;

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private XhsStoreMapper xhsStoreMapper;

    @Resource
    private XhsUserMapper xhsUserMapper;

    @Resource
    private ProductSyncService productSyncService;

    @Resource
    private XhsOrderMapper xhsOrderMapper;

    @Resource
    private PmsProductMapper productMapper;

    @Resource
    private PmsSkuStockMapper pmsSkuStockMapper;


    @Resource
    private XhsApiConfig apiConfig;

    @Resource
    private XhsLoginService xhsLoginService;


    // 允许的订单状态列表
    private static final List<Integer> ALLOWED_STATUS = Arrays.asList(2, 6, 7, 71, 998);

    @Override
    public VoucherVerifyResponse verifyVoucher(VoucherVerifyRequest request) throws Exception {
        try {
            // 1. 获取API地址
            String apiUrl = apiConfig.getBaseUrl() + "/api/rmp/mp/deal/voucher/verify";

            // 2. 获取有效access_token
            String accessToken = xhsLoginService.getValidToken();
            if (!StringUtils.hasText(accessToken)) {
                log.info("获取access_token失败");
            }

            // 3. 构建请求URL
            HttpUrl url = HttpUrl.parse(apiUrl).newBuilder()
                    .addQueryParameter("app_id", apiConfig.getAppId())
                    .addQueryParameter("access_token", accessToken)
                    .build();

            // 4. 构建请求体
            String jsonBody = objectMapper.writeValueAsString(request);
            log.info("核销请求入参:{}",jsonBody);
            RequestBody body = RequestBody.create(jsonBody, MediaType.parse("application/json"));

            // 5. 构建HTTP请求
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .build();

            // 6. 执行请求
            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    String errorMsg = String.format("凭证核销失败，状态码: %d", response.code());
                    log.error(errorMsg);
                }

                // 7. 解析响应
                String responseBody = response.body().string();
                VoucherVerifyResponse verifyResponse = objectMapper.readValue(responseBody, VoucherVerifyResponse.class);

                if (verifyResponse == null || verifyResponse.getData() == null) {
                    log.info("凭证核销响应数据解析失败");
                }

                // 8. 记录核销ID
                log.info("凭证核销成功，核销ID: {}", verifyResponse.getData().getVerifyId());

                return verifyResponse;
            }
        } catch (IOException e) {
            log.error("凭证核销网络异常", e);
        }
     return null;
    }










    @Override
    @Transactional
    public OrderUpsertResponse createOrder(CreateOrderRequest request) {

        PmsProduct product = productMapper.getById(request.getProductId());
        if (ObjectUtil.isEmpty(product)){
            log.error("商品信息不存在：{}",request.getProductId());
            throw new BaseException("商品信息不存在");
        }
        PmsSkuStock sku = pmsSkuStockMapper.selectByProductKey(product.getId());
        XhsOrder order = new XhsOrder();
         // 调用小红书

        order.setOutOrderId(OrderNumberUtils.generateNumericOrderNo(20));

        BigDecimal priceYuan = product.getOriginalPrice();
        BigDecimal promotionPrice = product.getPrice();
        BigDecimal totalYuan = priceYuan.multiply(new BigDecimal(request.getCount()));
        BigDecimal newYuan = promotionPrice.multiply(new BigDecimal(request.getCount()));

    // 转换为分后设置到订单对象
        //打着前价格
        order.setOrderPrice(AmountUtils.yuanToFen(totalYuan));
        //打折后价格
        order.setFinalPrice(AmountUtils.yuanToFen(newYuan));

        order.setOrderStatus(0);
        // 用户openid
        order.setOpenId(request.getOpenId());

        //小程序path路径
        order.setPath("/pages/pro-info/pro-info?id=" + product.getId());

        order.setBizCreateTime(new Date());
        // 当前时间加10分钟
        Date now = new Date();
        Date expiredTime = new Date(now.getTime() + 10 * 60 * 1000);
        order.setOrderExpiredTime(expiredTime);

        order.setProductId(Math.toIntExact(product.getId()));
        order.setSkuId(Math.toIntExact(sku.getId()));
        order.setPhone(request.getPhone());
        xhsOrderMapper.insert(order);

        // 调用小红书下单接口
        OrderUpsertRequest orderUpsertRequest = new OrderUpsertRequest();
        fillXhsRequest(orderUpsertRequest,order,request,product);
        OrderUpsertResponse orderUpsertResponse = this.upsertOrder(orderUpsertRequest);
        log.info("外部接收小红书创建订单信息：{}",orderUpsertResponse);
        OrderUpsertResponse.ResponseData xhsData = orderUpsertResponse.getData();
        XhsOrder xhsOrder = xhsOrderMapper.selectByOutOrderId(xhsData.getOutOrderId());
        xhsOrder.setXhsOrderId(xhsData.getOrderId());
        xhsOrder.setPayToken(xhsData.getPayToken());

        xhsOrderMapper.updateOrder(xhsOrder);
        return orderUpsertResponse;
    }

    /**
     * 填充小红书订单请求参数（修正价格计算逻辑）
     */
    private void fillXhsRequest(OrderUpsertRequest request, XhsOrder order,
                                CreateOrderRequest createRequest, PmsProduct product) {
        // 商品信息
        OrderUpsertRequest.ProductInfo productInfo = new OrderUpsertRequest.ProductInfo();
        productInfo.setOutProductId(String.valueOf(product.getId()));
        productInfo.setOutSkuId(String.valueOf(order.getSkuId()));
        productInfo.setNum(createRequest.getCount());

        // 价格计算（单位：分）
        long originalPrice = AmountUtils.yuanToFen(product.getOriginalPrice());
        long salePrice = AmountUtils.yuanToFen(product.getPrice());

        // 设置商品价格（必须满足 real_price = sale_price - ∑discounts）
        productInfo.setSalePrice(originalPrice);

        // 如果有折扣（原价 > 售价）
        if (originalPrice > salePrice) {
            long discountAmount = originalPrice - salePrice;

            // 设置折扣信息
            OrderUpsertRequest.DiscountInfo discountInfo = new OrderUpsertRequest.DiscountInfo();
            discountInfo.setName("商品折扣");
            discountInfo.setPrice(discountAmount);
            discountInfo.setNum(1);
            productInfo.setDiscountInfos(Collections.singletonList(discountInfo));

            // 实际价格 = 售价 - 折扣 = originalPrice - discountAmount
            productInfo.setRealPrice(salePrice);
        } else {
            // 无折扣时，实际价格 = 售价
            productInfo.setRealPrice(salePrice);
        }

        // 价格信息
        OrderUpsertRequest.PriceInfo priceInfo = new OrderUpsertRequest.PriceInfo();
        priceInfo.setOrderPrice(order.getFinalPrice());  // 订单总价（最终支付价格）
        priceInfo.setDiscountPrice(order.getOrderPrice() - order.getFinalPrice()); // 总优惠金额

        // 设置请求参数
        request.setProductInfos(Collections.singletonList(productInfo));
        request.setPriceInfo(priceInfo);
        request.setOutOrderId(order.getOutOrderId());
        request.setOpenId(order.getOpenId());
        request.setPath(order.getPath());
        request.setBizCreateTime(order.getBizCreateTime().getTime());
        request.setOrderExpiredTime(order.getOrderExpiredTime().getTime() / 1000); // 转换为秒
    }

    @Override
    public XhsOrder getOrderById(Long id) {
        return xhsOrderMapper.selectById(id);
    }

    @Override
    public XhsOrder getOrderByOutOrderId(String outOrderId) {
        return xhsOrderMapper.selectByOutOrderId(outOrderId);
    }

    @Override
    public String getOutOrderByVoucherCode(String voucherCode) {
        return xhsOrderMapper.getOutOrderByVoucherCode(voucherCode);
    }

    @Override
    public XhsOrder getOrderByXhsOrderId(String xhsOrderId) {
        return xhsOrderMapper.selectByXhsOrderId(xhsOrderId);
    }

    @Override
    public List<XhsOrder> getUserOrders(String openId) {
        return xhsOrderMapper.selectByOpenId(openId);
    }

    @Override
    @Transactional
    public boolean updateOrderStatus(Long id, Integer orderStatus) {
        return xhsOrderMapper.updateStatus(id, orderStatus) > 0;
    }

    @Override
    @Transactional
    public boolean updatePayInfo(Long id, String xhsOrderId, Integer payChannel,
                                 String payToken, Date payTime, Date payExpiredTime) {
        return xhsOrderMapper.updatePayInfo(id, xhsOrderId, payChannel, payToken, payTime, payExpiredTime) > 0;
    }

    @Override
    @Transactional
    public boolean updateCallbackStatus(Long id, Integer callbackStatus) {
        return xhsOrderMapper.updateCallbackStatus(id, callbackStatus) > 0;
    }

    @Override
    public List<XhsOrder> getOrderList(Date startTime, Date endTime, Integer orderStatus,
                                       Integer pageNum, Integer pageSize) {
        int offset = (pageNum - 1) * pageSize;
        return xhsOrderMapper.selectPage(startTime, endTime, orderStatus, offset, pageSize);
    }

    @Override
    public int countOrderList(Date startTime, Date endTime, Integer orderStatus) {
        return xhsOrderMapper.count(startTime, endTime, orderStatus);
    }

    @Override
    public List<OrderList> selXhsOrder(SelOrderRequest request) {

        List<XhsOrder> xhsOrderList = new ArrayList<>();
        if (!Objects.isNull(request.getType())){
            xhsOrderList= xhsOrderMapper.selectByStatus(request.getType(),request.getOpenId(),request.getVoucherCode(),request.getStoreId());
        }else {
            List<Integer> status = new ArrayList<>();
            status.add(1);
            status.add(0);
            status.add(5);
            xhsOrderList=   xhsOrderMapper.selectByStatuList(status,request.getOpenId());
        }

        if (CollectionUtils.isEmpty(xhsOrderList)){
            return new ArrayList<>();
        }

        List<OrderList> orderLists = new ArrayList<>();
        xhsOrderList.stream().forEach(xhsOrder -> {
            OrderList orderList = new OrderList();
            orderList.setOrderPrice(AmountUtils.fenToYuan(xhsOrder.getOrderPrice()));
            orderList.setFinalPrice(AmountUtils.fenToYuan(xhsOrder.getFinalPrice()));

            orderList.setOutProductId(xhsOrder.getProductId());
            PmsProduct product = productMapper.getById(Integer.valueOf(xhsOrder.getProductId()));
            orderList.setOutProductName(product.getName());
            orderList.setStatus(xhsOrder.getOrderStatus());
            orderList.setProduceDescription(product.getDescription());
            orderList.setProductImage(product.getPic());
            orderList.setSale(product.getSale());
            orderList.setPayToken(xhsOrder.getPayToken());
            orderList.setXhsOrderId(xhsOrder.getXhsOrderId());
            orderList.setOutOrderId(xhsOrder.getOutOrderId());
            orderList.setOpenId(xhsOrder.getOpenId());
            if (ObjectUtil.isNotEmpty(xhsOrder.getVerifyTime())){
                orderList.setVerificationTime(xhsOrder.getVerifyTime());
                XhsStore xhsStore = xhsStoreMapper.selectByPoiId(xhsOrder.getStoreId());
                orderList.setStoreName(xhsStore.getName());
                orderList.setVoucherCode(xhsOrder.getVoucherCode());
            }


            BigDecimal originalPrice = product.getOriginalPrice();
            BigDecimal price = product.getPrice();

            // 默认不打折
            double discount = 10.0;

            // 安全计算折扣
            if (originalPrice != null && originalPrice.compareTo(BigDecimal.ZERO) > 0) {
                discount = price.divide(originalPrice, 4, RoundingMode.HALF_UP)
                        .multiply(BigDecimal.TEN)
                        .setScale(1, RoundingMode.HALF_UP)
                        .doubleValue();
            }
            // 设置折扣
            orderList.setDiscount(discount);

            orderLists.add(orderList);
        });


        return orderLists;
    }



    @Override
    public OrderUpsertResponse upsertOrder(OrderUpsertRequest request) {
        // 1. 参数校验
        validateRequest(request);
        request.setBizCreateTime(System.currentTimeMillis());
//        request.setOrderExpiredTime(1800L);
//        long expiredTimeMillis = request.getBizCreateTime() + (request.getOrderExpiredTime() * 1000L);
//        request.setOrderExpiredTime(System.currentTimeMillis()+10 * 60 * 1000);

        long orderExpiredTimeSeconds = (System.currentTimeMillis() / 1000) + (10 * 60);
        request.setOrderExpiredTime(orderExpiredTimeSeconds);


        // 2. 获取API地址
        String apiUrl = apiConfig.getBaseUrl() + "/api/rmp/mp/deal/order/upsert";

        // 3. 获取有效token
        String validToken;
        try {
            validToken = xhsLoginService.getValidToken();
        } catch (XhsApiException e) {
            log.error("获取access_token失败", e);
            throw new RuntimeException("获取access_token失败", e);
        }

        try {
            // 4. 构建请求URL
            HttpUrl url = HttpUrl.parse(apiUrl).newBuilder()
                    .addQueryParameter("app_id", apiConfig.getAppId())
                    .addQueryParameter("access_token", validToken)
                    .build();

            // 5. 构建请求体
            String jsonBody = objectMapper.writeValueAsString(request);
            RequestBody body = RequestBody.create(jsonBody, MediaType.parse("application/json"));

            // 6. 构建HTTP请求
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .build();

            // 7. 执行请求并处理响应
            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    log.error("订单创建失败，HTTP状态码: {}", response.code());
                    throw new RuntimeException("API请求失败，状态码: " + response.code());
                }

                // 8. 解析响应数据
                String responseBody = response.body().string();
                OrderUpsertResponse orderUpsertResponse = objectMapper.readValue(responseBody, OrderUpsertResponse.class);
                log.info("创建订单返回信息：{}",orderUpsertResponse);
                return orderUpsertResponse;
            }
        } catch (IOException e) {
            log.error("订单创建异常", e);
            throw new RuntimeException("订单创建异常", e);
        }
    }

    /**
     * 校验请求参数
     */
    private void validateRequest(OrderUpsertRequest request) {
        // 校验商品数量（目前仅支持单商品）
        if (request.getProductInfos() == null || request.getProductInfos().size() != 1) {
            throw new IllegalArgumentException("目前仅支持单商品下单");
        }

        // 校验购买数量
        OrderUpsertRequest.ProductInfo productInfo = request.getProductInfos().get(0);
        if (productInfo.getNum() == null || productInfo.getNum() <= 0) {
            throw new IllegalArgumentException("商品购买数量必须大于0");
        }

        // 校验价格计算
        if (productInfo.getRealPrice() == null || productInfo.getSalePrice() == null) {
            throw new IllegalArgumentException("商品价格不能为空");
        }

        // 计算折扣总额
        long totalDiscount = 0;
        if (productInfo.getDiscountInfos() != null) {
            totalDiscount = productInfo.getDiscountInfos().stream()
                    .mapToLong(d -> d.getPrice() * d.getNum())
                    .sum();
        }

        // 校验实际价格 = 售卖价格 - 折扣总额
        if (!productInfo.getRealPrice().equals(productInfo.getSalePrice() - totalDiscount)) {
            throw new IllegalArgumentException("商品实际价格计算错误，应为: salePrice - totalDiscount");
        }

        // 校验订单总价计算
        if (request.getPriceInfo() != null && request.getPriceInfo().getOrderPrice() != null) {
            long calculatedPrice = productInfo.getRealPrice() * productInfo.getNum();
            if (request.getPriceInfo().getFreightPrice() != null) {
                calculatedPrice += request.getPriceInfo().getFreightPrice();
            }
//            if (request.getPriceInfo().getExtraPriceInfos() != null) {
//                calculatedPrice += request.getPriceInfo().getExtraPriceInfos().stream()
//                        .mapToLong(e -> e.getPrice() * e.getNum())
//                        .sum();
//            }
            if (!request.getPriceInfo().getOrderPrice().equals(calculatedPrice)) {
                throw new IllegalArgumentException("订单总价计算错误");
            }
        }
    }

























    @Override
    public XhsGpayOrderQueryResponse queryGpayOrder(XhsGpayOrderQueryRequest request) throws Exception {
        try {
            // 1. 获取API地址
            String apiUrl = apiConfig.getBaseUrl() + "/api/rmp/mp/deal/gpay_order/get";

            // 2. 获取有效access_token
            String accessToken = xhsLoginService.getValidToken();
            if (!StringUtils.hasText(accessToken)) {
                log.error("获取access_token失败");
                throw new Exception("获取access_token失败");
            }

            // 3. 构建请求体
            String requestBody = objectMapper.writeValueAsString(request);
            RequestBody body = RequestBody.create(
                    MediaType.parse("application/json; charset=utf-8"),
                    requestBody
            );

            // 4. 构建HTTP请求
            Request httpRequest = new Request.Builder()
                    .url(apiUrl)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("app_id", apiConfig.getAppId())
                    .addHeader("access_token", accessToken)
                    .build();

            // 5. 执行请求
            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    log.error("查询担保支付订单失败，状态码: {}", response.code());
                    throw new Exception("查询担保支付订单失败，状态码: " + response.code());
                }

                // 6. 解析响应
                String responseBody = response.body().string();
                XhsGpayOrderQueryResponse responseObj = objectMapper.readValue(
                        responseBody,
                        new TypeReference<XhsGpayOrderQueryResponse>() {}
                );

                if (responseObj == null || !responseObj.getSuccess()) {
                    log.error("担保支付订单查询响应数据解析失败: {}", responseObj != null ? responseObj.getMsg() : "null");
                    throw new Exception("担保支付订单查询响应数据解析失败: " +
                            (responseObj != null ? responseObj.getMsg() : "null"));
                }

                // 7. 记录获取结果
                log.info("成功查询担保支付订单，订单ID: {}, 状态: {}",
                        responseObj.getData().getOrderId(),
                        responseObj.getData().getOrderStatus());

                return responseObj;
            }
        } catch (IOException e) {
            log.error("查询担保支付订单网络异常", e);
            throw new Exception("查询担保支付订单网络异常", e);
        }
    }

    @Override
    public OrderDetail getOrderInfo(XhsGpayOrderQueryRequest request) {
        // 定义重试策略
        Retryer<OrderDetail> retryer = RetryerBuilder.<OrderDetail>newBuilder()
                .retryIfException(e -> {

                    if (e instanceof XhsApiException) {
                        return e.getMessage().contains("redis上锁失败");
                    }
                    // 其他异常也重试
                    return true;
                })
                .retryIfResult(response -> response == null)
                .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))
                .withStopStrategy(StopStrategies.stopAfterAttempt(10))
                .build();

        try {
            return retryer.call(() -> {
                try {
                    XhsOrder xhsOrder = xhsOrderMapper.selectByOutOrderId(request.getOutOrderId());
                    if (xhsOrder == null) {
                        throw new RuntimeException("未找到订单信息，outOrderId: " + request.getOutOrderId());
                    }

                    PmsProduct product = productMapper.selectByPrimaryKey(Long.valueOf(xhsOrder.getProductId()));
                    if (product == null) {
                        throw new RuntimeException("未找到商品信息，productId: " + xhsOrder.getProductId());
                    }

                    OrderDetail orderDetail = new OrderDetail();
                    orderDetail.setOrderPrice(BigDecimal.valueOf(xhsOrder.getOrderPrice()).divide(BigDecimal.valueOf(100)));
                    orderDetail.setFinalPrice(BigDecimal.valueOf(xhsOrder.getFinalPrice()).divide(BigDecimal.valueOf(100)));
                    orderDetail.setOutOrderId(xhsOrder.getOutOrderId());
                    orderDetail.setProductImage(product.getPic());
                    orderDetail.setVoucherCode(xhsOrder.getVoucherCode());
                    orderDetail.setOutProductName(product.getName());
                    orderDetail.setOutProductId(Math.toIntExact(product.getId()));
                    orderDetail.setPayTime(xhsOrder.getPayTime());
                    orderDetail.setPhone(xhsOrder.getPhone());
                    orderDetail.setCreateTime(xhsOrder.getCreateTime());
                    orderDetail.setProductCount(1);
                    orderDetail.setStatus(xhsOrder.getOrderStatus());

                    // 处理门店信息（可能失败的点）
                    if (xhsOrder.getOrderStatus().equals(5)) {
                        XhsStore xhsStore = xhsStoreMapper.selectByPoiId(xhsOrder.getStoreId());
                        if (xhsStore == null) {
                            throw new RuntimeException("未找到门店信息，storeId: " + xhsOrder.getStoreId());
                        }
                        orderDetail.setStoreName(xhsStore.getName());
                        orderDetail.setVerificationTime(xhsOrder.getVerifyTime());
                    }

                    if (ObjectUtil.isNotEmpty(xhsOrder.getVoucherCodeImage())) {
                        orderDetail.setVoucherCodeImage(xhsOrder.getVoucherCodeImage());
                    }

                    // 处理商品详情（外部服务调用）
                    ProductDetailVo detailProduct = productSyncService.getDetailProduct(Math.toIntExact(product.getId()));
                    if (ObjectUtil.isNotEmpty(detailProduct)) {
                        orderDetail.setProductStatus(detailProduct.getStatus() == 1 ? 1 : 2);
                    }

                    return orderDetail;
                } catch (Exception e) {
                    log.error("订单详情获取异常，请求参数: {}", request, e);
                    throw new RuntimeException("订单详情获取异常", e);
                }
            });
        } catch (RetryException | ExecutionException e) {
            log.error("订单详情获取重试3次后仍失败，请求参数: {}", request, e);
            throw new RuntimeException("订单详情获取重试多次后失败", e);
        }
    }








    @Override
    public Code2SessionResponse code2Session(Code2SessionRequest request) {
        // 1. 参数校验
        if (request == null || request.getCode() == null || request.getCode().isEmpty()) {
            throw new IllegalArgumentException("code不能为空");
        }

        // 2. 获取API地址
        String apiUrl = apiConfig.getBaseUrl() + "/api/rmp/session";

        // 3. 获取有效token
        String validToken;
        try {
            validToken = xhsLoginService.getValidToken();
        } catch (XhsApiException e) {
            log.error("获取access_token失败", e);
            throw new RuntimeException("获取access_token失败", e);
        }

        try {
            // 4. 构建请求URL
            HttpUrl url = HttpUrl.parse(apiUrl).newBuilder()
                    .addQueryParameter("app_id", apiConfig.getAppId())
                    .addQueryParameter("access_token", validToken)
                    .addQueryParameter("code", request.getCode())
                    .build();

            // 5. 构建HTTP请求
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .get()
                    .build();

            // 6. 执行请求并处理响应
            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    log.error("code2Session失败，HTTP状态码: {}", response.code());
                    throw new RuntimeException("API请求失败，状态码: " + response.code());
                }

                // 7. 解析响应数据
                String responseBody = response.body().string();
                log.info("解析数据：{}",responseBody);
                return objectMapper.readValue(responseBody, Code2SessionResponse.class);
            }
        } catch (IOException e) {
            log.error("code2Session异常", e);
            throw new RuntimeException("code2Session异常", e);
        }
    }

    @Override
    public StoreDetailVo getStoreDetail(StoreDetailRequest storeDetailRequest) {
        XhsUser xhsUser = xhsUserMapper.selectByPhoneNumber(storeDetailRequest.getPhone());
        if (ObjectUtil.isEmpty(xhsUser)){
            throw new BaseException("用户不存在");
        }
        XhsStore xhsStore = xhsStoreMapper.selectByPhone(storeDetailRequest.getPhone());
        if (ObjectUtil.isEmpty(xhsStore)){
            throw new BaseException("该用户没有店铺信息哦");
        }
        // 所有订单
        StoreDetailVo storeDetailVo = new StoreDetailVo();
        storeDetailVo.setStoreName(xhsStore.getName());
        storeDetailVo.setPhone(storeDetailRequest.getPhone());
        storeDetailVo.setStoreId(xhsStore.getPoiId());

        List<XhsOrder> xhsOrderList = xhsOrderMapper.selbystroreId(xhsStore.getPoiId());
        if (CollectionUtils.isEmpty(xhsOrderList)){
            return storeDetailVo;
        }
        LocalDateTime yesterdayStart = LocalDate.now().minusDays(1).atStartOfDay();
        LocalDateTime yesterdayEnd = yesterdayStart.plusDays(1);
        Date yesterdayStartDate = Date.from(yesterdayStart.atZone(ZoneId.systemDefault()).toInstant());
        Date yesterdayEndDate = Date.from(yesterdayEnd.atZone(ZoneId.systemDefault()).toInstant());

        BigDecimal verificationMoney = xhsOrderList.stream()
                .filter(order -> order.getOrderStatus() == 5)
                .map(order -> BigDecimal.valueOf(order.getFinalPrice()).divide(BigDecimal.valueOf(100)))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        int verificationCount = (int) xhsOrderList.stream()
                .filter(order -> order.getOrderStatus() == 5)
                .count();

        BigDecimal yesterdayVerificationMoney = xhsOrderList.stream()
                .filter(order -> order.getOrderStatus() == 5)
                .filter(order -> order.getCreateTime() != null)
                .filter(order -> !order.getCreateTime().before(yesterdayStartDate) &&
                        order.getCreateTime().before(yesterdayEndDate))
                .map(order -> BigDecimal.valueOf(order.getFinalPrice()).divide(BigDecimal.valueOf(100)))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        int yesterdayVerificationCount = (int) xhsOrderList.stream()
                .filter(order -> order.getOrderStatus() == 5)
                .filter(order -> order.getCreateTime() != null)
                .filter(order -> !order.getCreateTime().before(yesterdayStartDate) &&
                        order.getCreateTime().before(yesterdayEndDate))
                .count();

        storeDetailVo.setVerificationMoney(verificationMoney);
        storeDetailVo.setVerificationCount(verificationCount);
        storeDetailVo.setYesterdayVerificationMoney(yesterdayVerificationMoney);
        storeDetailVo.setYesterdayVerificationCount(yesterdayVerificationCount);

        return storeDetailVo;
    }

    @Override
    public void updateOrder(VoucherVerifyRequest request) {

        XhsOrder xhsOrder = xhsOrderMapper.selectByOutOrderId(request.getOutOrderId());
        if (ObjectUtil.isEmpty(xhsOrder)){
            throw new BaseException("订单不存在");
        }
        xhsOrderMapper.updateOrderDetail(request.getOutOrderId(),request.getPoiId());
    }

    @Override
    public XhsPreAuthCodeResponse getPreAuthCode() {
        try {
            // 1. 获取API地址
            String apiUrl = apiConfig.getBaseUrl() + "/api/rmp/tp/pre_auth_code";

            // 2. 获取有效access_token
            String accessToken = null;
            try {
                accessToken = xhsLoginService.getValidToken();
            } catch (XhsApiException e) {
                throw new RuntimeException(e);
            }
            if (!StringUtils.hasText(accessToken)) {
                log.error("获取access_token失败");
                try {
                    throw new XhsApiException("获取access_token失败");
                } catch (XhsApiException e) {
                    throw new RuntimeException(e);
                }
            }

            // 3. 构建请求URL
            HttpUrl url = HttpUrl.parse(apiUrl).newBuilder()
                    .addQueryParameter("app_id", apiConfig.getAppId())
                    .addQueryParameter("access_token", accessToken)
                    .build();

            // 4. 构建空请求体
            RequestBody body = RequestBody.create("{}", MediaType.parse("application/json"));

            // 5. 构建HTTP请求
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .build();

            // 6. 执行请求
            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    String errorMsg = String.format("获取预授权码失败，状态码: %d", response.code());
                    log.error(errorMsg);
                    throw new BaseException(errorMsg);
                }

                // 7. 解析响应
                String responseBody = response.body().string();
                XhsPreAuthCodeResponse authResponse = objectMapper.readValue(
                        responseBody,
                        XhsPreAuthCodeResponse.class);

                if (authResponse == null || !authResponse.isSuccess()) {
                    String errorMsg = authResponse != null ?
                            authResponse.getMsg() : "响应数据解析失败";
                    log.error("获取预授权码失败: {}", errorMsg);
                    throw new BaseException("获取预授权码失败: " + errorMsg);
                }

                // 8. 记录获取结果
                log.info("成功获取预授权码: {}, 有效期: {}秒",
                        authResponse.getData().getPre_auth_code(),
                        authResponse.getData().getExpire_in());

                return authResponse;
            }
        } catch (IOException e) {
            log.error("获取预授权码网络异常", e);
            throw new BaseException("获取预授权码网络异常", e);
        }
    }












    @Override
    public CouponVerifyResponseDTO getByCouponCodes(List<String> couponCodes) {
        CouponVerifyRequestDTO request = new CouponVerifyRequestDTO();
        request.setCoupon_code_list(couponCodes);
        return callApi( request);
    }

    @Override
    public CouponVerifyResponseDTO getByOrderIds(List<String> orderIds) {
        CouponVerifyRequestDTO request = new CouponVerifyRequestDTO();
        request.setOrder_id_list(orderIds);
        return callApi(request);
    }

    @Override
    public CouponVerifyResponseDTO getVerifyDetail(List<String> couponCodes, List<String> orderIds) {
        CouponVerifyRequestDTO request = new CouponVerifyRequestDTO();
        request.setCoupon_code_list(couponCodes);
        request.setOrder_id_list(orderIds);
        return callApi(request);
    }

    /**
     * 调用小红书API查询核销信息
     */
    private CouponVerifyResponseDTO callApi(CouponVerifyRequestDTO request) {
        // 1. 参数校验
        validateRequest(request);

        // 2. 获取有效token
        String validToken;
        try {
            validToken =  xhsLoginService.getValidToken();
        } catch (XhsApiException e) {
            log.error("获取access_token失败", e);
            throw new BaseException("获取access_token失败", e);
        }

        try {
            // 3. 构建请求URL
            HttpUrl url = HttpUrl.parse(apiConfig.getBaseUrl() + "/api/rmp/v2/component/deal/order/coupon_verify_detail/get").newBuilder()
                    .addQueryParameter("app_id", apiConfig.getAppId())
                    .addQueryParameter("access_token", validToken)
                    .build();

            // 4. 构建请求体
            String jsonBody = JSON.toJSONString(request);
            log.info("请求参数: {}", jsonBody);
            RequestBody body = RequestBody.create(jsonBody, MediaType.parse("application/json"));

            // 5. 构建HTTP请求
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .build();

            // 6. 执行请求并处理响应
            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    log.error("查询核销信息失败，HTTP状态码: {}", response.code());
                    throw new BaseException("API请求失败，状态码: " + response.code());
                }

                // 7. 解析响应数据
                String responseBody = response.body().string();
                CouponVerifyResponseDTO verifyResponse = JSON.parseObject(responseBody, CouponVerifyResponseDTO.class);

                if (verifyResponse == null || !verifyResponse.getSuccess()) {
                    log.error("核销信息查询响应数据解析失败: {}", verifyResponse != null ? verifyResponse.getMsg() : "null");
                    throw new BaseException("核销信息查询响应数据解析失败: " +
                            (verifyResponse != null ? verifyResponse.getMsg() : "null"));
                }

                // 8. 记录获取结果
                log.info("成功查询核销信息，查询参数: {}", request);
                return verifyResponse;
            }
        } catch (IOException e) {
            log.error("查询核销信息网络异常", e);
            throw new BaseException("查询核销信息网络异常", e);
        }
    }

    /**
     * 校验请求参数
     */
    private void validateRequest(CouponVerifyRequestDTO request) {
        if (request == null) {
            throw new BaseException("请求参数不能为空");
        }

        // 校验至少提供一种查询条件
        if ((request.getCoupon_code_list() == null || request.getCoupon_code_list().isEmpty()) &&
                (request.getOrder_id_list() == null || request.getOrder_id_list().isEmpty())) {
            throw new BaseException("必须提供券码列表或订单列表");
        }

        // 校验券码数量限制
        if (request.getCoupon_code_list() != null && request.getCoupon_code_list().size() > 100) {
            throw new BaseException("券码列表最多支持100个");
        }

        // 校验订单数量限制
        if (request.getOrder_id_list() != null && request.getOrder_id_list().size() > 50) {
            throw new BaseException("订单列表最多支持50个");
        }
    }

    // ========== 新增方法实现：订单列表管理 ==========

    @Override
    public CommonPage<XhsOrderVO> getOrderList(XhsOrderQueryParam queryParam, Integer pageNum, Integer pageSize) {
        log.info("分页查询订单列表，参数：{}, 页码：{}, 页大小：{}", queryParam, pageNum, pageSize);

        // 设置分页参数
        PageHelper.startPage(pageNum, pageSize);

        // 查询订单列表
        List<Map<String, Object>> orderMapList = xhsOrderMapper.selectOrderListWithProduct(
            queryParam.getKeyword(),
            queryParam.getStatusList(),
            queryParam.getOrderStatus(),
            queryParam.getStartTime(),
            queryParam.getEndTime()
        );

        // 统计总数
        long total = xhsOrderMapper.countOrderList(
            queryParam.getKeyword(),
            queryParam.getStatusList(),
            queryParam.getOrderStatus(),
            queryParam.getStartTime(),
            queryParam.getEndTime()
        );

        // 转换为VO对象
        List<XhsOrderVO> orderVOList = new ArrayList<>();
        for (Map<String, Object> orderMap : orderMapList) {
            XhsOrderVO orderVO = convertMapToOrderVO(orderMap);
            orderVOList.add(orderVO);
        }

        // 构造分页结果
        CommonPage<XhsOrderVO> result = new CommonPage<>();
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setTotal(total);
        result.setTotalPage((int) Math.ceil((double) total / pageSize));
        result.setList(orderVOList);

        log.info("查询完成，共{}条记录", total);
        return result;
    }

    @Override
    public XhsOrderDetailVO getOrderDetail(Long id) {
        log.info("查询订单详情，订单ID：{}", id);

        Map<String, Object> orderMap = xhsOrderMapper.selectOrderDetailWithProduct(id);
        if (orderMap == null) {
            log.warn("订单不存在，订单ID：{}", id);
            return null;
        }

        XhsOrderDetailVO detailVO = convertMapToOrderDetailVO(orderMap);
        log.info("订单详情查询完成，订单号：{}", detailVO.getOutOrderId());
        return detailVO;
    }

    @Override
    @Transactional
    public boolean batchDeleteOrders(List<Long> ids) {
        log.info("批量删除订单，订单ID列表：{}", ids);

        if (CollectionUtils.isEmpty(ids)) {
            log.warn("订单ID列表为空");
            return false;
        }

        // 检查订单状态，只允许删除已完成的订单
        List<XhsOrder> orders = xhsOrderMapper.selectByIdList(ids);
        for (XhsOrder order : orders) {
            if (order.getOrderStatus() == null ||
                (order.getOrderStatus() != 3 && order.getOrderStatus() != 4 && order.getOrderStatus() != 5)) {
                log.error("订单状态不允许删除，订单ID：{}，状态：{}", order.getId(), order.getOrderStatus());
                throw new BaseException("只能删除已关闭、已退款或已使用的订单");
            }
        }

        // 执行批量删除（软删除，设置状态为999）
        int affectedRows = xhsOrderMapper.batchUpdateDeleteStatus(ids, new Date());
        log.info("批量删除完成，影响行数：{}", affectedRows);

        return affectedRows > 0;
    }

    @Override
    @Transactional
    public boolean batchCloseOrders(List<Long> ids, String reason) {
        log.info("批量关闭订单，订单ID列表：{}，关闭原因：{}", ids, reason);

        if (CollectionUtils.isEmpty(ids)) {
            log.warn("订单ID列表为空");
            return false;
        }

        // 检查订单状态，只允许关闭待付款和待使用的订单
        List<XhsOrder> orders = xhsOrderMapper.selectByIdList(ids);
        for (XhsOrder order : orders) {
            if (order.getOrderStatus() == null ||
                (order.getOrderStatus() != 0 && order.getOrderStatus() != 1)) {
                log.error("订单状态不允许关闭，订单ID：{}，状态：{}", order.getId(), order.getOrderStatus());
                throw new BaseException("只能关闭待付款或待使用的订单");
            }
        }

        // 执行批量关闭
        int affectedRows = xhsOrderMapper.batchCloseOrders(ids, reason, new Date());
        log.info("批量关闭完成，影响行数：{}", affectedRows);

        return affectedRows > 0;
    }

    @Override
    public boolean isOrderExpired(XhsOrder order) {
        if (order == null || order.getOrderExpiredTime() == null) {
            return false;
        }
        return isOrderExpired(order.getOrderExpiredTime());
    }

    @Override
    public boolean isOrderExpired(Date orderExpiredTime) {
        if (orderExpiredTime == null) {
            return false;
        }
        return orderExpiredTime.before(new Date());
    }

    @Override
    public List<String> getAvailableActions(Integer orderStatus, Boolean isExpired) {
        List<String> actions = new ArrayList<>();

        // 所有订单都可以查看
        actions.add("view");

        if (isExpired != null && isExpired) {
            // 过期订单只能查看和删除
            actions.add("delete");
        } else if (orderStatus != null) {
            switch (orderStatus) {
                case 0: // 待付款
                    actions.add("track");
                    actions.add("close");
                    break;
                case 1: // 待使用
                    actions.add("track");
                    actions.add("close");
                    break;
                case 2: // 支付失败
                    actions.add("delete");
                    break;
                case 3: // 已关闭
                    actions.add("delete");
                    break;
                case 4: // 已退款
                    actions.add("delete");
                    break;
                case 5: // 已使用
                    actions.add("delete");
                    break;
                default:
                    // 未知状态只能查看
                    break;
            }
        }

        return actions;
    }

    /**
     * 将Map转换为XhsOrderVO
     */
    private XhsOrderVO convertMapToOrderVO(Map<String, Object> orderMap) {
        XhsOrderVO orderVO = new XhsOrderVO();

        // 基础信息
        orderVO.setId(getLongValue(orderMap, "id"));
        orderVO.setOutOrderId(getStringValue(orderMap, "outOrderId"));
        orderVO.setPhone(getStringValue(orderMap, "phone"));
        orderVO.setProductId(getIntegerValue(orderMap, "productId"));
        orderVO.setProductName(getStringValue(orderMap, "productName"));

        // 金额信息（自动设置元格式）
        orderVO.setFinalPrice(getLongValue(orderMap, "finalPrice"));

        // 支付方式（自动设置文本）
        orderVO.setPayChannel(getIntegerValue(orderMap, "payChannel"));

        // 时间信息
        orderVO.setCreateTime(getDateValue(orderMap, "createTime"));
        orderVO.setPayTime(getDateValue(orderMap, "payTime"));
        orderVO.setOrderExpiredTime(getDateValue(orderMap, "orderExpiredTime"));

        // 状态处理 - 直接使用数据库状态，不进行过期判断
        Integer orderStatus = getIntegerValue(orderMap, "orderStatus");
        orderVO.setDisplayStatus(orderStatus, false);

        // 可用操作
        orderVO.setAvailableActions(getAvailableActions(orderStatus, false));

        return orderVO;
    }

    /**
     * 将Map转换为XhsOrderDetailVO
     */
    private XhsOrderDetailVO convertMapToOrderDetailVO(Map<String, Object> orderMap) {
        XhsOrderDetailVO detailVO = new XhsOrderDetailVO();

        // 基础信息
        detailVO.setId(getLongValue(orderMap, "id"));
        detailVO.setOutOrderId(getStringValue(orderMap, "outOrderId"));
        detailVO.setXhsOrderId(getStringValue(orderMap, "xhsOrderId"));
        detailVO.setPhone(getStringValue(orderMap, "phone"));
        detailVO.setOpenId(getStringValue(orderMap, "openId"));
        detailVO.setAppId(getStringValue(orderMap, "appId"));

        // 商品信息
        detailVO.setProductId(getIntegerValue(orderMap, "productId"));
        detailVO.setProductName(getStringValue(orderMap, "productName"));
        detailVO.setProductImage(getStringValue(orderMap, "productImage"));
        detailVO.setSkuId(getIntegerValue(orderMap, "skuId"));

        // 金额信息（自动设置元格式）
        detailVO.setOrderPrice(getLongValue(orderMap, "orderPrice"));
        detailVO.setFinalPrice(getLongValue(orderMap, "finalPrice"));
        detailVO.setFreightPrice(getLongValue(orderMap, "freightPrice"));
        detailVO.setDiscountPrice(getLongValue(orderMap, "discountPrice"));

        // 支付信息
        detailVO.setPayChannel(getIntegerValue(orderMap, "payChannel"));
        detailVO.setPayToken(getStringValue(orderMap, "payToken"));
        detailVO.setOpenPayType(getStringValue(orderMap, "openPayType"));
        detailVO.setCallbackStatus(getIntegerValue(orderMap, "callbackStatus"));

        // 券码信息
        detailVO.setVoucherCode(getStringValue(orderMap, "voucherCode"));
        detailVO.setVoucherCodeImage(getStringValue(orderMap, "voucherCodeImage"));

        // 其他信息
        detailVO.setStoreId(getStringValue(orderMap, "storeId"));
        detailVO.setPath(getStringValue(orderMap, "path"));

        // 时间信息
        detailVO.setPayTime(getDateValue(orderMap, "payTime"));
        detailVO.setPayExpiredTime(getDateValue(orderMap, "payExpiredTime"));
        detailVO.setOrderExpiredTime(getDateValue(orderMap, "orderExpiredTime"));
        detailVO.setBizCreateTime(getDateValue(orderMap, "bizCreateTime"));
        detailVO.setBizUpdateTime(getDateValue(orderMap, "bizUpdateTime"));
        detailVO.setCreateTime(getDateValue(orderMap, "createTime"));
        detailVO.setUpdateTime(getDateValue(orderMap, "updateTime"));
        detailVO.setVerifyTime(getDateValue(orderMap, "verifyTime"));

        // 状态处理 - 直接使用数据库状态，不进行过期判断
        Integer orderStatus = getIntegerValue(orderMap, "orderStatus");
        detailVO.setDisplayStatus(orderStatus, false);

        return detailVO;
    }

    /**
     * Map取值辅助方法
     */
    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : null;
    }

    private Long getLongValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return null;
        if (value instanceof Long) return (Long) value;
        if (value instanceof Integer) return ((Integer) value).longValue();
        if (value instanceof String) {
            try {
                return Long.parseLong((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    private Integer getIntegerValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return null;
        if (value instanceof Integer) return (Integer) value;
        if (value instanceof Long) return ((Long) value).intValue();
        if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    private Date getDateValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        // 先处理 LocalDateTime 的情况
        if (value instanceof LocalDateTime) {
            LocalDateTime ldt = (LocalDateTime) value;
            // 按系统默认时区转成 Instant，再转成 Date
            return Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
        }
        // 原来的 Date、Timestamp 判断
        if (value instanceof Date) {
            return (Date) value;
        }
        if (value instanceof java.sql.Timestamp) {
            return new Date(((java.sql.Timestamp) value).getTime());
        }
        return null;
    }
}
